#ifndef COURSE_H_
#define COURSE_H_

#include <vector>
#include <string>
#include "requirement.h"
#include <boost/shared_ptr.hpp>

class CourseSection;
/// A requirement and a representation of a course.
class Course : public Requirement {


	std::string courseID;
	std::string description;
    double credits;
    boost::shared_ptr<Requirement> prereqs;
	std::vector< boost::shared_ptr<CourseSection> > sections_;

public:
	Course();
	Course(const Course&);
	Course& operator=(const Course&);
	Course(const std::string&);
    ~Course();

	std::string getCourseID() const;
	std::string getDescription() const;
    double getCredits() const;
    boost::shared_ptr<Requirement> prerequisites() const;
	void prerequisites(boost::shared_ptr<Requirement> requirements);
	std::vector< boost::shared_ptr<CourseSection> > getLectures() const;

	bool addSection(boost::shared_ptr<CourseSection> section);

	bool operator==(const Course&) const;
	bool operator!=(const Course&) const;
	bool operator<(const Course&) const;
	bool operator<=(const Course&) const;
	bool operator>(const Course&) const;
	bool operator>=(const Course&) const;
	/* The remaining functions would exist to modify courses, 
	 * something which the end-user would not need to do.
	 * They are therefore not as important.
	 */
	//	void setCourseID();
    void setDescription(const std::string& newDesc);
	//void removeDep(const Course&);
	//void addDep(const Course& dep);
	void setCredits(const double value);
	
    bool evaluate(Context&);
    std::string to_string(Context&);
    std::size_t count(Context&);
    std::list<Course> courses();
};

std::ostream& operator<<(std::ostream& output, const Course& s);

#endif
